package model;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;

import javax.swing.table.AbstractTableModel;

public class DeviceTableModel extends AbstractTableModel {
	private static final long serialVersionUID = 8233404764388265676L;
	private ArrayList<ArrayList<Object>> data;
	private ArrayList<String> columnnames;
	private Connection connect;
	private ResultSet rs;
	private ArrayList<Device> listChange;
	private DeviceTableModel tableModel;
	private DateFormat dateFormat;

	public DeviceTableModel() {
		this.dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		this.data = new ArrayList<ArrayList<Object>>();
		this.columnnames = new ArrayList<String>(Arrays.asList("STT",
				"Mã sản phẩm", "Tên sản phẩm", "Loại sản phẩm", "Nhà sản xuất",
				"Ngày nhập", "Giá mua", "Giá bán", "Bảo hành(tháng)",
				"Số lượng tồn kho"));
		loadData("SELECT * FROM device");
		this.listChange = new ArrayList<Device>();
	}

	public Object getValueAt(int row, int column) {
		Device d = (Device) data.get(row).get(0);
		switch (column) {
		case 0:
			return row + 1;
		case 1:
			return d.getId();
		case 2:
			return d.getName();
		case 3:
			return d.getType();
		case 4:
			return d.getProvider();
		case 5:
			return dateFormat.format(d.getInputDay());
		case 6:
			return d.getBuyPrice();
		case 7:
			return d.getSellPrice();
		case 8:
			return d.getGuarantee();
		case 9:
			return data.get(row).get(1);
		}
		return null;
	}

	public int getRowCount() {
		if (data == null)
			return 0;
		return data.size();
	}

	public int columnCount() {
		return columnnames.size();
	}

	public String getColumnName(int column) {
		return columnnames.get(column);
	}

	public boolean isCellEditable(int row, int column) {
		return true;
	}

	@Override
	public int getColumnCount() {
		return columnnames.size();
	}

	@Override
	public Class<?> getColumnClass(int columnIndex) {
		switch (columnIndex) {
		case 0:
			return Integer.class;
		case 6:
		case 7:
			return Double.class;
		case 8:
		case 9:
			return Integer.class;
		default:
			return String.class;
		}
	}

	public void loadData(PreparedStatement pre) {
		try {
			rs = pre.executeQuery();
			data.clear();
			ArrayList<Object> tmp = null;

			while (rs.next()) {
				tmp = new ArrayList<Object>();
				Device d = new Device();
				d.setId(rs.getString("id"));
				d.setName(rs.getString("name"));
				d.setType(rs.getString("type"));
				d.setProvider(rs.getString("provider"));
				d.setInputDay(rs.getDate("inputday"));
				d.setBuyPrice(rs.getDouble("buyprice"));
				d.setSellPrice(rs.getDouble("sellprice"));
				d.setGuarantee(rs.getByte("guarantee"));

				tmp.add(d);
				tmp.add(rs.getInt("amount"));
				data.add(tmp);
			}

			fireTableDataChanged();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (rs != null) {
					rs.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	public void loadData(String sql) {
		try {
			if (connect == null)
				connect = model.Database.connect();
			PreparedStatement pre = connect.prepareStatement(sql);

			loadData(pre);
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally {
			try {
				if (rs != null) {
					rs.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	public Object getDataRow(int row) {
		return this.data.get(row);
	}

	// TODO
	public void save() {
		for (Device d : listChange) {
			// TODO some code
			try {
				connect = Database.connect();
				String sql = "UPDATE device SET id =?,name=?,WHERE id=?";
				PreparedStatement pre = connect.prepareStatement(sql);
				pre.setString(1, d.getId());
				pre.setString(2, d.getName());
				pre.setString(3, d.getType());
				pre.setString(4, d.getProvider());
				pre.setDate(5, (java.sql.Date) d.getInputDay());
				pre.setDouble(6, d.getSellPrice());
				pre.setDouble(7, d.getBuyPrice());
				pre.setInt(8, d.getGuarantee());
				pre.setInt(9, d.getAmount());
				pre.executeUpdate();
				tableModel.loadData(sql);

			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		listChange.clear();
	}

	public void setValueAt(Object aValue, int row, int column) {
		Device d = (Device) data.get(row).get(0);
		Device oldDevice = d;
		switch (column) {
		case 1:
			d.setId((String) aValue);
			break;
		case 2:
			d.setName((String) aValue);
			break;
		case 3:
			d.setType((String) aValue);
			break;
		case 4:
			d.setProvider((String) aValue);
			break;
		case 5:
			DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
			try {
				d.setInputDay(format.parse((String) aValue));
			} catch (ParseException e) {
				OptionMessenger.showMessageDialog(null,
						"Định dạng ngày không hợp lệ", "Lỗi",
						OptionMessenger.ERROR_MESSAGE);
				return;
			}
			break;
		case 6:
			d.setBuyPrice((double) aValue);
			break;
		case 7:
			d.setSellPrice((double) aValue);
			break;
		case 8:
			d.setGuarantee((int) aValue);
			break;
		case 9:
			d.setAmount((int) aValue);
			break;
		}
		if (!oldDevice.equals(d))
			this.listChange.add(d);
	}
}